/*************************************************************************
	> File Name: vitural_table.cpp
	> Author: ma6174
	> Mail: ma6174@163.com 
	> Created Time: 2015年07月15日 星期三 10时06分55秒
 ************************************************************************/

#include<iostream>

using namespace std;

class Base {
public:
	//构造函数或者析构函数中调用虚函数，均为自身类型定义的版本
	//派生类的构造过程中，首先执行基类的构造函数，再执行本身的构造函数
	//派生类的析构过程中，首先执行派生类的析构函数，然后再依构造顺序的逆序撤销它的基类
	Base() { f(); cout << "Base构造函数初始化..." << endl; }
	virtual void f() { cout << "Base::f" << endl;}
	virtual void g() { cout << "Base::g" << endl; }
	virtual void h() { cout << "Base::h" << endl; }
	virtual ~Base() {  cout << "Base析构函数执行..." << endl; }

};

class Base2 {
public :
    Base2() { cout << "Base2构造函数初始化。。。" << endl; }
    virtual void f() {cout << "Base2::f" << endl; }
    virtual void a() {cout << "Base2::a" << endl; }
    virtual ~Base2() {cout << "Base2析构函数。。。" << endl; }
};

class Derive : public Base, public Base2{
public:
	Derive() { f(); cout << "Derive构造函数初始化..." << endl; }
	virtual void f() {cout << "Derive::f" << endl; }
	virtual void k() { cout << "Derive::k" << endl; }
	virtual ~Derive() {  cout << "Derive析构函数执行..." << endl; }
};

int main(void) {
	typedef void(*Fun)(void);
	Fun pFun = NULL;
    
	{
	Base b;
	cout << "虚函数表地址：" << *(long *)(&b) << endl;
	cout << "虚函数第一个函数地址：" << *(long *)*(long *)(&b) << endl;
	cout << "虚函数第二个函数地址：" << *((long *)*(long *)(&b) + 1) << endl;
	cout << "虚函数第三个函数地址：" << *((long *)*(long *)(&b) + 2) << endl;
    cout << "虚函数第四个函数地址：" << *((long *)*(long *)(&b) + 3) << endl;
    //访问虚函数表的地址

	long **vtable = (long **)&b;
	cout << "虚函数第一个函数地址：" << vtable[0][0] << endl;
	cout << "虚函数第二个函数地址：" << vtable[0][1] << endl;
	cout << "虚函数第三个函数地址：" << vtable[0][2] << endl;


	//invoke the first virtual function
	pFun = (Fun)*((long *)*(long *)(&b));
	pFun();
	pFun = (Fun)*((long *)*(long *)(&b) + 1);
	pFun();
	pFun = (Fun)*((long *)*(long *)(&b) + 2);
	pFun();
	}
    cout << "\n" << endl;
	{
	Derive d;
	cout << "虚函数表地址：" << *(long *)(&d) << endl;
	cout << "虚函数第一个函数地址：" << *(long *)*(long *)(&d) << endl;
	cout << "虚函数第二个函数地址：" << *((long *)*(long *)(&d) + 1) << endl;
	cout << "虚函数第三个函数地址：" << *((long *)*(long *)(&d) + 2) << endl;
	cout << "虚函数第四个函数地址：" << *((long *)*(long *)(&d) + 3) << endl;
    cout << "虚函数第五个函数地址：" << *((long *)*(long *)(&d) + 4) << endl;
	pFun = (Fun)*((long *)*(long *)(&d));
	pFun();
	pFun = (Fun)*((long *)*(long *)(&d) + 1);
	pFun();
	pFun = (Fun)*((long *)*(long *)(&d) + 2);
	pFun();
	//基类和派生类的虚析构函数占据&d + 3 / 4
	pFun = (Fun)*((long *)*(long *)(&d) + 5);
	pFun();

    pFun = (Fun)*(long *)*((long *)(&d) + 1);
    pFun();
    pFun = (Fun)*((long *)*((long *)(&d) + 1) + 1);
    pFun();
	}
    cout << "\n" << endl;
    {
        Base2 *b2 = new Derive();
        //cout << "虚函数表地址：" << *(long *)b2 << endl;
        //pFun = (Fun)*((long *)*((long *)b2) + 1);
        //pFun();
        //虚析构函数
        //pFun = (Fun)*((long *)*((long *)b2 - 1) + 4);
        //pFun();
        //b2->~Base2();
        delete b2;
    }
	cout << "finished..." << endl;
	return 0;
}
